package com.example.test.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;


public class RandCodeUtil {


    /**
     * 放到session中的key
     */
    public static final String RAN_DOM_CODE_KEY = "ran_dom_code_key";
    
    private Random random = new Random();
    
    /**
     * 随机产生的字符串
     */
    private String randString = "0123456789";
    
    /**
     * 图片宽
     */
    private int width = 120;

    /**
     * 图片高
     */
    private int height = 50;

    /**
     * 干扰线数量
     */
    private int lineSize = 40;

    /**
     * 随机产生字符数量
     */
    private int stringNum = 4;
    

    /**
     * 生成随机图片
     */
    public void getRandCode(HttpServletRequest request,
                            HttpServletResponse response,
                            RedisTemplate<Object, Object> myRedisTemplate) {

        //BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
        //产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,18));
        g.setColor(getRandColor(160, 200));
        //绘制干扰线
        for(int i=0;i<=lineSize;i++){
            drawLine(g);
        }
        //绘制随机字符
        String randomString = "";
        for(int i=1;i<=stringNum;i++){
            randomString = drawString(g, randomString, i);
        }
        List<String> randCodeList = (List<String>) myRedisTemplate.opsForValue().get(RAN_DOM_CODE_KEY);
        if(randCodeList == null){
            randCodeList = new ArrayList<>();
        }
        randCodeList.add(randomString);
        myRedisTemplate.opsForValue().set(RAN_DOM_CODE_KEY, randCodeList, 15, TimeUnit.MINUTES);
        g.dispose();
        try {
            //将内存中的图片通过流动形式输出到客户端
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 验证码校验方法
     * @param code 用户输入的验证码
     * @param myRedisTemplate redis字符串操作对象
     * @return
     */
    public static boolean validate(String code, RedisTemplate<Object, Object> myRedisTemplate){
        boolean checkResult = false;
        List<String> randCodeList = (List<String>) myRedisTemplate.opsForValue().get(RAN_DOM_CODE_KEY);
        for(int i = 0 ; i < randCodeList.size() ; i ++ ){
            if(randCodeList.get(i).equals(code)){
                checkResult = true;
                randCodeList.remove(code);
                break;
            }
        }
        myRedisTemplate.opsForValue().set(RAN_DOM_CODE_KEY, randCodeList, 15, TimeUnit.MINUTES);
        return checkResult;
    }



    /**
     * 获得字体
     * @return
     */
    private Font getFont(){
        return new Font("Fixedsys",Font.CENTER_BASELINE,25);
    }

    /**
     * 获得颜色
     * @param fc
     * @param bc
     * @return
     */
    private Color getRandColor(int fc,int bc){
        if(fc > 255){
            fc = 255;
        }
        if(bc > 255){
            bc = 255;
        }
        int r = fc + random.nextInt(bc-fc-16);
        int g = fc + random.nextInt(bc-fc-14);
        int b = fc + random.nextInt(bc-fc-18);
        return new Color(r,g,b);
    }

    /**
     * 绘制字符串
     * @param g
     * @param randomString
     * @param i
     * @return
     */
    private String drawString(Graphics g, String randomString, int i){
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101),random.nextInt(111),random.nextInt(121)));
        String rand = String.valueOf(getRandomString(random.nextInt(randString.length())));
        randomString += rand;
        g.translate(random.nextInt(3), random.nextInt(3));
        g.drawString(rand, 20 * i, 35);
        return randomString;
    }

    /**
     * 绘制干扰线
     * @param g
     */
    private void drawLine(Graphics g){
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.drawLine(x, y, x+xl, y+yl);
    }

    /**
     * 获取随机的字符
     * @param num
     * @return
     */
    public String getRandomString(int num){
        return String.valueOf(randString.charAt(num));
    }



}
